package genetic;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 亚明生产车间调度算法实例
 *
 * @author lin
 */
public class Run {
    public static void main(String[] args) {
        System.out.println("开始执行！");
        // 程序运行开始时间
        Date startTime = new Date();
        // 创建遗传集合结构体
        GeneticModel geneticModel = new GeneticModel();
        // 设置生产基本信息
        // 每行为一个工单
        // 每个list的内容为工序，[0]为工位编号， [1]为加工耗时
        List<List<MesStationJobBo>> jobList = Arrays.asList(
                Arrays.asList(new MesStationJobBo("90bb2acb-d815-4a05-acb1-c15435748cac",10L,"工单1",11L),
                        new MesStationJobBo("3793781b-3ce9-4dca-a31b-e471cde76512",15L,"工单1",12L),
                        new MesStationJobBo("db8c25c4-8886-42bc-b4da-eaa1d67cb4b4",50L,"工单1",130L),
                        new MesStationJobBo("99070f4c-dc19-498a-93fa-66861a680a0f",30L,"工单1",140L),
                        new MesStationJobBo("99070f4c-dc19-498a-93fa-66861a680a0f",20L,"工单1",150L)),
                Arrays.asList(new MesStationJobBo("3793781b-3ce9-4dca-a31b-e471cde76512",15L,"工单2",11L),
                        new MesStationJobBo("791765f5-2ecd-4e53-98c3-97ba68b88c41",20L,"工单2",12L),
                        new MesStationJobBo("90bb2acb-d815-4a05-acb1-c15435748cac",60L,"工单2",13L),
                        new MesStationJobBo("99070f4c-dc19-498a-93fa-66861a680a0f",50L,"工单2",14L),
                        new MesStationJobBo("db8c25c4-8886-42bc-b4da-eaa1d67cb4b4",40L,"工单2",15L)),
                Arrays.asList(new MesStationJobBo("90bb2acb-d815-4a05-acb1-c15435748cac",10L,"工单3",1L),
                        new MesStationJobBo("3793781b-3ce9-4dca-a31b-e471cde76512",15L,"工单3",2L),
                        new MesStationJobBo("db8c25c4-8886-42bc-b4da-eaa1d67cb4b4",50L,"工单3",3L),
                        new MesStationJobBo("99070f4c-dc19-498a-93fa-66861a680a0f",30L,"工单3",4L),
                        new MesStationJobBo("791765f5-2ecd-4e53-98c3-97ba68b88c41",20L,"工单3",5L))
                );
        //取出所有工位
        List<String> firstNumbers = new ArrayList<>();
        for (List<MesStationJobBo> sublist : jobList) {
            for (MesStationJobBo job : sublist) {
                firstNumbers.add(job.getWorkStationIdData());
            }
        }
        firstNumbers = firstNumbers.stream().distinct().collect(Collectors.toList());
        // 设定初始工位数量和工单数量
        int workOrderNum = jobList.size(), stationNum = firstNumbers.size();
        // 初始化遗传算法
        GeneticAlgorithm geneticAlgorithm = new GeneticAlgorithm(geneticModel, workOrderNum, stationNum);
        // 计算当前工序和工位生产关系的最优解
        Long minTime = GeneticAlgorithm.optimalSolution(geneticModel, jobList, firstNumbers);
        // 输出最优解
        System.out.println("最优解总耗时：" + minTime);
        System.out.println("目前遗传代数：" + geneticModel.getPopulationNumber());
        // 开始计算
        Result result = geneticAlgorithm.run(geneticModel, jobList, minTime);
        // 获取程序计算出来的最优解
        Map<String, Map<Long, String>> stationMatrixMap = geneticModel.getStationMatrixMap();
        // 耗时
        Map<String, Map<Long, Long>> timeMatrixMap = geneticModel.getTimeMatrixMap();
        // 输出程序计算出来的最优解
        System.out.println("计算最优总耗时：" + result.getFulfillTime());

        // 输出结果，结果格式自行调整
        for (List<MesStationJobBo> mesStationJobBoList : jobList) {
            for (MesStationJobBo mesStationJobBo : mesStationJobBoList) {
                if (mesStationJobBo!=null){
                    String workOrderIdData = mesStationJobBo.getWorkOrderIdData();
                    Long sort = mesStationJobBo.getProcessSortData();
                    System.out.printf("工单: %s, 工序: %d, 工位: %s, 开始时间: %d, 结束时间: %d ,耗时: %d%n",
                            workOrderIdData,
                            sort,
                            stationMatrixMap.get(workOrderIdData).get(sort),
                            result.getStartTimeMap().get(workOrderIdData).get(sort),
                            result.getEndTimeMap().get(workOrderIdData).get(sort),
                            timeMatrixMap.get(workOrderIdData).get(sort));
                }
            }
        }
        System.out.println("算法结束！");
        System.out.println("程序用时：" + (new Date().getTime() - startTime.getTime()) / 1000);
    }
}
